#include <WiFi.h>
#include <WebServer.h>

// WiFi配置
const char* ssid = "matepad";
const char* password = "12345678";

// 创建Web服务器，监听80端口
WebServer server(80);

// 全局变量angle
int angle = 0;

// HTML网页内容
const char* html = R"=====(
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ESP32角度控制</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; padding: 20px; }
        .container { max-width: 400px; margin: 0 auto; }
        .slider { width: 100%; height: 15px; border-radius: 5px; background: #ddd; outline: none; }
        .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 25px; height: 25px; border-radius: 50%; background: #4CAF50; cursor: pointer; }
        button { padding: 10px 20px; margin: 5px; background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; }
        button:hover { background-color: #45a049; }
        .angle-value { font-size: 24px; font-weight: bold; margin: 20px 0; }
    </style>
</head>
<body>
    <div class="container">
        <h1>ESP32角度控制</h1>
        
        <div class="angle-value">当前角度: <span id="angle-display">0</span>°</div>
        
        <input type="range" id="angle-slider" min="0" max="180" value="0" class="slider"
               oninput="updateDisplay(this.value)" onchange="setAngle(this.value)">
        
        <div style="margin-top: 20px;">
            <button onclick="setAngle(0)">0°</button>
            <button onclick="setAngle(90)">90°</button>
            <button onclick="setAngle(180)">180°</button>
            <button onclick="setAngle(document.getElementById('angle-slider').value)">设置角度</button>
        </div>
        
        <div style="margin-top: 20px; font-size: 14px; color: #666;">
            IP: <span id="esp32-ip">%IP%</span>
        </div>
    </div>

    <script>
        // 更新显示
        function updateDisplay(value) {
            document.getElementById('angle-display').textContent = value;
        }

        // 发送角度到ESP32
        function setAngle(value) {
            // 添加加载状态
            const buttons = document.querySelectorAll('button');
            buttons.forEach(btn => {
                btn.disabled = true;
                btn.style.opacity = '0.7';
            });
            
            fetch('/set?angle=' + value)
                .then(response => {
                    if (!response.ok) {
                        throw new Error('服务器响应错误: ' + response.status);
                    }
                    return response.text();
                })
                .then(data => {
                    updateDisplay(data);
                    console.log('角度已设置为: ' + data);
                    
                    // 显示成功提示
                    const successMsg = document.createElement('div');
                    successMsg.textContent = '设置成功!';
                    successMsg.style.color = 'green';
                    successMsg.style.marginTop = '10px';
                    document.querySelector('.container').appendChild(successMsg);
                    
                    // 3秒后移除提示
                    setTimeout(() => {
                        successMsg.remove();
                    }, 3000);
                })
                .catch(error => {
                    console.error('Error:', error);
                    alert('设置角度失败，请检查ESP32连接');
                })
                .finally(() => {
                    // 恢复按钮状态
                    buttons.forEach(btn => {
                        btn.disabled = false;
                        btn.style.opacity = '1';
                    });
                });
        }

        // 页面加载时获取当前角度
        fetch('/get')
            .then(response => response.text())
            .then(data => {
                updateDisplay(data);
                document.getElementById('angle-slider').value = data;
            })
            .catch(error => {
                console.error('Error:', error);
                alert('无法获取当前角度，请检查ESP32连接');
            });
        
        // 替换IP地址占位符
        document.getElementById('esp32-ip').textContent = window.location.hostname;
    </script>
</body>
</html>
)=====";

String packDataWithPadding(const String& data) {
  // 计算基础长度（包头1 + 长度1 + 数据 + 包尾1）
  size_t baseLength = 3 + data.length();

  // 计算需要的填充字节数
  size_t paddingNeeded = (4 - (baseLength % 4)) % 4;

  // 构建数据包
  String packet;
  packet.reserve(baseLength + paddingNeeded);  // 预分配空间提高效率

  // 添加包头
  packet += (char)0xAA;

  // 添加数据长度（注意限制长度不超过255）
  packet += (char)(data.length() & 0xFF);

  // 添加数据
  packet += data;

  // 添加填充和包尾
  if (paddingNeeded == 0) {
    packet += (char)0xFF;
    packet += (char)0xFF;  // 添加额外填充确保总长度不是4的倍数
  } else {
    packet += (char)0xFF;  // 包尾
    // 不需要额外填充，因为baseLength + 1已经不是4的倍数
  }

  return packet;
}


// 处理根路径请求，返回HTML页面
void handleRoot() {
  server.send(200, "text/html", html);
} /**
 * 将整数转换为三位字符串，不足三位时前补零
 * 例如：1 → "001", 180 → "180"
 * @param num 要转换的整数（范围0-999）
 * @return 三位字符串表示
 */
String toThreeDigitString(int num) {
  // 限制数值范围
  if (num < 0) num = 0;
  if (num > 999) num = 999;

  // 转换为三位字符串
  if (num < 10) {
    return "00" + String(num);
  } else if (num < 100) {
    return "0" + String(num);
  } else {
    return String(num);
  }
}

// 处理设置角度请求
void handleSetAngle() {
  if (server.hasArg("angle")) {
    angle = server.arg("angle").toInt();
    // 限制角度范围
    if (angle < 0) angle = 0;
    if (angle > 180) angle = 180;

    // 通过串口打印角度值
    Serial.print("角度已设置为: ");

    String data = "+00," + toThreeDigitString(angle) + ",f";
    Serial.println(data);
    Serial2.print(packDataWithPadding(data));


    server.send(200, "text/plain", String(angle));
  } else {
    server.send(400, "text/plain", "错误: 缺少angle参数");
  }
}

// 处理获取当前角度请求
void handleGetAngle() {
  server.send(200, "text/plain", String(angle));
}

void setup() {
  // 初始化串口通信
  Serial.begin(115200);
  Serial2.begin(9600);
  Serial.println("\n启动中...");

  // 连接WiFi
  WiFi.begin(ssid, password);
  Serial.print("连接到WiFi");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nWiFi连接成功");
  Serial.print("IP地址: ");
  Serial.println(WiFi.localIP());

  // 设置服务器路由
  server.on("/", handleRoot);
  server.on("/set", handleSetAngle);
  server.on("/get", handleGetAngle);

  // 启动服务器
  server.begin();
  Serial.println("HTTP服务器已启动");
}




void loop() {
  // 处理客户端请求
  server.handleClient();
}